
#include <mantle.h>
#include <cfile.h>
#include <zfile.h>


struct fd_t{
    CFile * file;
    wchar_t * wszName;
    int offset;
};
/*  ----------------------------------- Macros */

#define SEEK_SET        0       /* Seek from beginning of file.  */
#define SEEK_CUR        1       /* Seek from current position.  */
#define SEEK_END        2       /* Seek from end of file.  */

extern int zopen(const char * filename, int openflags)
{

    struct fd_t* fd = (struct fd_t*)malloc(sizeof(struct fd_t));
    if(fd == 0)return -1;
    fd->offset = 0;

    fd->wszName = (wchar_t *)malloc(strlen(filename)+1);
    if(fd->wszName == 0)return -1;
    AnsiToUnic(fd->wszName, filename);

    CFile* pfile = new CFile();
    ECode ec = pfile->Init(fd->wszName);
    if (FAILED(ec))return -1;

    fd->file = pfile;

    return (int)fd;
}

extern int zwrite(int fd, void * buff, int nbytes)
{
    struct fd_t* filed = (fd_t*)fd;
    int size = filed->file->GetSize();

    if(size < filed->offset+nbytes)nbytes = size - filed->offset;

    ECode ec = filed->file->Write(filed->offset, nbytes, buff);
    if (FAILED(ec))return 0;
    return nbytes;
}

extern int zread(int fd, void * buff, int nbytes)
{
    struct fd_t* filed = (fd_t*)fd;
    int size = filed->file->GetSize();

    if(size < filed->offset+nbytes)nbytes = size - filed->offset;

    ECode ec = filed->file->Read(filed->offset, nbytes, buff);
    if (FAILED(ec))return 0;
    return nbytes;
}

extern int zseek(int fd, int offset, int whence)
{
    struct fd_t* filed = (fd_t*)fd;
    int loc = filed->offset;
    int size = filed->file->GetSize();
    switch (whence)
    {
        case SEEK_SET:
            filed->offset = offset;
            break;
        case SEEK_CUR:
            filed->offset += offset;
            break;
        case SEEK_END:
            filed->offset = filed->file->GetSize() + offset;
            break;
        default: break;
    }
    if(filed->offset > size) return -1;
    return loc;
}

extern int zclose(int fd)
{
    struct fd_t* filed = (fd_t*)fd;
    delete filed->file;
    free(filed->wszName);
    free(filed);
    return 0;
}

extern int zdatazync(int fd)
{

    return 0;
}

extern int zstat(char* filename, void * stat)
{

    return 0;
}

extern int zremove(const char * filename)
{

    return 0;
}

extern int zmkdir(const char * filename)
{

    return 0;
}

extern int zopendir(const char * filename, void * dir_p)
{

    return 0;
}

extern int zreaddir(void * dir_p, void * buff, int size)
{

    return 0;
}

extern int zclosedir(void * dir_p)
{

    return 0;
}
